use rama::{
    Service,
    error::{ErrorContext as _, OpaqueError},
    http::{
        Request, Response, StatusCode, body::util::BodyExt as _, convert::curl,
        service::web::response::IntoResponse as _,
    },
    ua::layer::emulate::UserAgentEmulateHttpRequestModifier,
};

use super::writer::Writer;

#[derive(Debug, Clone)]
pub(super) struct CurlWriter {
    pub(super) writer: Writer,
}

impl Service<Request> for CurlWriter {
    type Error = OpaqueError;
    type Response = Response;

    async fn serve(&self, req: Request) -> Result<Self::Response, Self::Error> {
        let Ok(req) = UserAgentEmulateHttpRequestModifier::new().serve(req).await else {
            return Ok((StatusCode::INTERNAL_SERVER_ERROR, "failed to emulate UA").into_response());
        };

        let (parts, body) = req.into_parts();
        let payload = body.collect().await.unwrap().to_bytes();
        let curl_cmd = curl::cmd_string_for_request_parts_and_payload(&parts, &payload);

        self.writer
            .write_bytes(curl_cmd.as_bytes())
            .await
            .context("write curl command")?;

        Ok(StatusCode::OK.into_response())
    }
}
